package com.yhy.dubbo.service.mongo;

import com.yhy.domain.mongo.*;
import com.yhy.domain.vo.PageResult;
import com.yhy.dubbo.api.mongo.PublishApi;
import com.yhy.dubbo.service.utils.IdService;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class PublishApiImpl implements PublishApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;


    @Override
    public String save(Publish publish) {
        //1.把自己发布的动态放到总动态集合表(quanzi_publish)里
        publish.setId(ObjectId.get());
        publish.setCreated(System.currentTimeMillis());
        publish.setPid(idService.getNextId("publish"));
        mongoTemplate.save(publish);

        //2.把自己发布的动态放到自己的相册表(quanzi_album_自己的userId)
        Album album = new Album();
        album.setId(ObjectId.get());
        album.setPublishId(publish.getId());
        album.setCreated(System.currentTimeMillis());
        mongoTemplate.save(album,"quanzi_album_"+publish.getUserId());

        //3.为了把动态放到好友的时间线表 所以先查询当前用户的好友关系表(tanhua_users)
        Criteria criteria = Criteria.where("userId").is(publish.getUserId());
        Query query = new Query(criteria);
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //4.根据获取的friendList 把动态放入好友各自的时间线表(quanzi_time_line_好友的userId)
        for (Friend friend : friendList) {
            TimeLine timeLine = new TimeLine();
            timeLine.setId(ObjectId.get());
            timeLine.setUserId(publish.getUserId());
            timeLine.setPublishId(publish.getId());
            timeLine.setCreated(System.currentTimeMillis());
            mongoTemplate.save(timeLine,"quanzi_time_line_"+friend.getFriendId());
        }

        return publish.getId().toHexString();
    }

    @Override
    public PageResult findMovementsByUid(Integer page, Integer pagesize, Long userId) {
//        1.首先确定自己的时间线表
        String collectionName = "quanzi_time_line_"+userId;

//        2.查询总数
        long count = mongoTemplate.count(new Query(), collectionName);

//        3.根据时间倒序 从自己的时间线表中取出数据 封装成Publish
        Query query = new Query()
                .skip((page-1)*pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, collectionName);
        List<Publish> list = new ArrayList<>();
        for (TimeLine timeLine : timeLineList) {
            Publish publish = mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
            list.add(publish);
        }
        return new PageResult(page,pagesize, (int) count,list);
    }

    @Override
    public PageResult findMovementsByRecommend(Integer page, Integer pagesize, Long userId) {

//        1.查询总数
        Criteria criteria = Criteria.where("userId").is(userId);

        long count = mongoTemplate.count(new Query(criteria), RecommendUser.class);

//        2.查询分页数据
        Query query = new Query(criteria)
                .skip((page-1)*pagesize).limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<RecommendQuanzi> recommendQuanziList = mongoTemplate.find(query, RecommendQuanzi.class);
        List<Publish> list = new ArrayList<>();
        for (RecommendQuanzi recommendQuanzi : recommendQuanziList) {
            Publish publish = mongoTemplate.findById(recommendQuanzi.getPublishId(), Publish.class);
            if(publish.getState()==1){
                list.add(publish);
            }
        }
        return new PageResult(page,pagesize, (int) count,list);
    }

    @Override
    public PageResult findOwnMovements(Integer page, Integer pagesize, Long userId) {

        String collectionName = "quanzi_album_"+userId;

        long count = mongoTemplate.count(new Query(), Album.class, collectionName);

        Query query = new Query()
                .skip((page-1)*pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));

        List<Album> albumList = mongoTemplate.find(query, Album.class, collectionName);
        List<Publish> list = new ArrayList<>();
        for (Album album : albumList) {
            Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
            if(publish.getState()==1){
                list.add(publish);
            }
        }
        return new PageResult(page,pagesize, (int) count,list);
    }

    @Override
    public Publish findMovementDetailById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    @Override
    public PageResult findAll(Integer page, Integer pagesize, Long uid, Integer state) {
        Query query = new Query();
        if(uid != null){
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if(state != null){
            query.addCriteria(Criteria.where("state").is(state));
        }

        long count = mongoTemplate.count(query, Publish.class);

        query.skip((page - 1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        return new PageResult(page,pagesize, (int) count,publishList);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    @Override
    public void updateState(String publishId, Integer state) {
        Criteria criteria = Criteria.where("id").is(new ObjectId(publishId));
        Update update = new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(new Query(criteria),update,Publish.class);
    }

    @Override
    public Publish findByPid(Long pid) {
        Criteria criteria = Criteria.where("pid").is(pid).and("state").is(1);
        return mongoTemplate.findOne(new Query(criteria),Publish.class);
    }

}